package triangleWorm;

import processing.core.*;
import processing.opengl.*;

@SuppressWarnings({ "serial", "unused" })
public class WormApplication extends PApplet {	
	public final static int WIDTH = 1000;
	public final static int HEIGHT = 800;
	
	//World
	private IWorld world;
	
	//Worm
	private IWorm worm;
	private int extraNum = 5;
	private IWorm[] extraWorms = new IWorm[extraNum];
	
	//Camera
	PVector eye;
	float eyeDist = 200;
	float eyeX = width / 2f;
	float eyeY = height / 2f;
	float eyeZ;
	
	//Perspective
	float fov = PI / 2.5f;
	float aspect = WIDTH / HEIGHT;
	float near = 100f;
	float far = 10000f;
	
	
	public void setup() {
		size(WIDTH, HEIGHT, OPENGL);
		noStroke();
		
		//Instantiate world
		//world = new SimpleWorld();
		world = new IslandWorld();
		world.init(this);
		
		//Instantiate worm movement
		IWormMovement movement = new MouseMovement(); //Mouse setup
		//IWormMovement movement = new SimpleNoiseMovement(); //'Random' movement
		//IWormMovement movement = new SinusMovement(); //Oscillating in world
		movement.init(this, world.getSize(), world.getCenter());
		
		//Instantiate worm
		//worm = new SimpleWorm3D(); //Drawn with ellipse
		//worm = new StickWorm(); //Draw worm as lines
		worm = new TriangleWorm();
		worm.init(this, movement);
		
		//Extra worms
		for(int i = 0; i < extraNum; i ++) {
			//setup behavior for extra worms
			IWormMovement extraMovement = new SinusMovement(); //Oscillating in world
			extraMovement.init(this, world.getSize(), world.getCenter());
			//Initiate worms
			extraWorms[i] = new TriangleWorm();
			extraWorms[i].init(this, extraMovement);			
		}
		
		//Setup eye for camera
		eyeDist += worm.getLength() * 3f;
		eyeZ = worm.getPosition().z - eyeDist;
		eye = new PVector(eyeX, eyeY, eyeZ);
	}
	
	public void draw() {
		/*---Update---*/
		world.update();
		worm.update();
		for(int i = 0; i < extraNum; i ++) {
			extraWorms[i].update();			
		}
		
		

		/*---Draw--*/
		//Lights
		lights();
		/*
		ambientLight(128f, 128f, 128f);
		directionalLight(128f, 128f, 128f, 0f, 0f, -1f);
		lightFalloff(1f, 0f, 0f);
		lightSpecular(0f, 0f, 0f);
		*/
		
		//Camera
		perspective(fov, aspect, near, far);
		//Calculate camera position
		if(PVector.dist(worm.getPosition(), eye) > eyeDist) {
			eye = PVector.sub(eye, worm.getPosition());
			eye.normalize();
			eye.mult(eyeDist);
			eye.add(worm.getPosition());
		}
		camera(eye.x, eye.y, eye.z, // eyeX, eyeY, eyeZ (camera position)
				worm.getPosition().x, worm.getPosition().y, worm.getPosition().z, // centerX, centerY, centerZ (look at)
			   0f, 1f, 0f); // upX, upY, upZ
		
		//Action
		world.draw();		
		worm.draw();
		for(int i = 0; i < extraNum; i ++) {
			extraWorms[i].draw();			
		}
		//Drama!
	}
	
	public void mouseMoved() {
	}
	
	public void mousePressed() {
	}
	
	public void mouseReleased() {		
	}
	
	public void mouseDragged() {
	}	
	
	public void keyPressed() {	
	}
	
	public static void main(String[] args) {
		PApplet.main(new String[] {"--present",triangleWorm.WormApplication.class.getName()});
	}
}
